package flatlandAgent;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FlatlandPanel extends JPanel{

	private static final long serialVersionUID = 1L;
	
	private FlatlandModel model;
	
	private final int labelSize = 46; 
	private final int insets = 5;
	private int frameSize = 40; 

//	private boolean initPanel = true; 
	private static ImageIcon food; 
	private static ImageIcon poison; 
	private static ImageIcon blank; 
	private static ImageIcon player; 
	
	
	public FlatlandPanel(FlatlandModel model){
		this.model = model; 
		initGUI(); 
	}

	
	private void initGUI(){
		setIconLabes(); 
		this.setLayout(new GridBagLayout());
		//drawGame(); 
	}
	
	public void drawGame(){
		this.removeAll(); 
		int dimentions = model.getMapDimention();
		for (int i = 0; i < dimentions; i ++){
			for (int j = 0; j < dimentions; j++){
				if (i != model.getPosX() || j != model.getPosY()){
					drawCell(i,j); 
				}
			}
		}

		drawPlayer();
		this.validate();
//		this.repaint(); 
	}
	
	private void drawPlayer(){
		
		final Image image = player.getImage(); 
		final int width = player.getIconWidth(); 
		final int height = player.getIconHeight(); 
		
		final double rotation = getRotation();
		
		JPanel playerPanel = new JPanel() {
			private static final long serialVersionUID = 1L;

			@Override
            public Dimension getPreferredSize() {
                return new Dimension(width, height);
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
                g2.rotate(rotation, width / 2, height / 2);
                g2.drawImage(image, 0, 0, null);
            }
        };
        
        GridBagConstraints con = getGridConstraints(model.getPosX(), model.getPosY()); 
        this.add(playerPanel,con); 
	}


	private double getRotation() {
		switch (model.getHeading()) {
		case 'f':
			return 0;
		case 'l':
			return -Math.PI/2;
		case 'r':
			return Math.PI/2;
		case 'd':
			return Math.PI;
		}
		return 0; 
	}
	
	private void drawCell(int i, int j){
		GridBagConstraints con = getGridConstraints(i, j); 
		JLabel icon = getIcon(model.getCell(i, j));
		JPanel panel = new JPanel(); 
		panel.add(icon); 
		this.add(panel,con); 
	}


	private GridBagConstraints getGridConstraints(int i, int j) {
		GridBagConstraints con = new GridBagConstraints(); 
//		con.insets = new Insets(insets,insets,insets,insets);
		con.gridx = i; 
		con.gridy = j;
		return con;
	}

	private JLabel getIcon(char cell) {
		switch (cell) {
		case '.':
			return new JLabel(blank);
		case 'f': 
			return new JLabel(food);
		case 'p': 
			return new JLabel(poison);
		case 'c': 
			return new JLabel(player);
		}
		return null; 
	}
	

 	private void setIconLabes(){
		if (!(food == null && poison == null && blank == null && player == null)){
//			System.out.println("We are saving time in setIconLabes");
			return; 
		}
		food = (new ImageIcon(readImage('f')));
		poison = (new ImageIcon(readImage('p')));
		blank = (new ImageIcon(readImage('.')));
		player = (new ImageIcon(readImage('c')));
	}
	
	private Image readImage(char cell) {
		BufferedImage image = null; 
		String path = new File("").getAbsolutePath();
		FileSystem fileSys = FileSystems.getDefault();
		String sep = fileSys.getSeparator();
		
		try {
			switch (cell) {
			case '.':
				image = ImageIO.read(new File(path + sep + "src" + sep + "flatlandAgent" + sep + "icons" + sep + "blank.png"));
				break;
			case 'f': 
				image = ImageIO.read(new File(path + sep + "src" + sep + "flatlandAgent" + sep + "icons" + sep + "cheese.png"));
				break;
			case 'p': 
				image = ImageIO.read(new File(path + sep + "src" + sep + "flatlandAgent" + sep + "icons" + sep + "poison.png"));
				break;
			case 'c': 
				image = ImageIO.read(new File(path + sep + "src" + sep + "flatlandAgent" + sep + "icons" + sep + "swipe_up.png"));
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		Image theimage = image.getScaledInstance(labelSize, labelSize, Image.SCALE_SMOOTH); 
		return theimage;
	}
	
	@Override
	public Dimension getPreferredSize(){
		int size = 2*insets + model.getMapDimention()*(insets+labelSize) + this.frameSize; 
		return new Dimension(size, size); 
	}
	@Override
	public Dimension getMinimumSize(){
		int size = 2*insets + model.getMapDimention()*(insets+labelSize) +  this.frameSize ; 
		return new Dimension(size, size); 
	}
	
	@Override 
	public void paint(Graphics g){
//		g.fillRect(0, 0, g, height);
		super.paint(g); 
//		if (initPanel) {
//			int size = 2*insets + model.getMapDimention()*(insets+labelSize);
//			g.setColor(getBackground()); 
//			g.fillRect(0, 0, size, size);
//			g.setColor(getForeground()); 
//			int dimention = model.getMapDimention(); 
//			for (int i = 0; i < dimention; i++) {
//				for (int j = 0; j < dimention; j++) {
//					paintIcon(i,j,g);
//				}
//			}
//			initPanel = false; 
//		} else {
//			paintIcon(model.getPreviusPosX(), model.getPreviusPosY(), g); 
//		}
//		paintPlayer(g);
	}


//	private void paintIcon(int i, int j, Graphics g) {
//		int startPosX = getPanelPos(i); 
//		int startPosY = getPanelPos(j);
//		ImageIcon icon = getIcon(model.getCell(i, j));
//		Image image = icon.getImage();
//		g.drawImage(image, startPosX, startPosY, getBackground(), null);
//	}
//
//	private int getPanelPos(int x) {
//		return 2 * insets + x * (insets + labelSize);
//	}
//
//	private void paintPlayer(Graphics g) {
//		final Image image = player.getImage();
//		int size = labelSize;
//		int startPosX = getPanelPos(model.getPosX());
//		int startPosY = getPanelPos(model.getPosY());
//
//		final double rotation = getRotation();
//
//		Graphics2D g2 = (Graphics2D) g;
//		g2.rotate(rotation, size / 2, size / 2);
//		g2.drawImage(image, startPosX, startPosY, getBackground(), null);
//	}

}
